package fun.hijklmn.magic.admin.server.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import fun.hijklmn.magic.admin.server.properties.JwtProperties;
import fun.hijklmn.magic.admin.server.handler.JwtHandler;
import fun.hijklmn.magic.admin.server.pojo.SysUser;
import fun.hijklmn.magic.common.constants.CharsetConstant;
import fun.hijklmn.magic.common.constants.ContentTypeConstant;
import fun.hijklmn.magic.common.enums.ResponseCodeEnum;
import fun.hijklmn.magic.common.utils.JsonUtil;
import fun.hijklmn.magic.common.utils.ResultVOUtil;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;

/**
 * @Description
 * @Author fs
 * @Date 2021/6/25 18:14
 * @Version 0.0.1-SNAPSHOT
 **/
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private JwtHandler jwtHandler;

    private JwtProperties jwtProperties;

    private AuthenticationManager authenticationManager;

    private ThreadLocal<Integer> rememberMe = new ThreadLocal<>();

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager, JwtProperties jwtProperties, JwtHandler jwtHandler) {
        super(authenticationManager);
        this.jwtProperties = jwtProperties;
        this.jwtHandler = jwtHandler;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try {
            SysUser sysUser = new ObjectMapper().readValue(request.getInputStream(), SysUser.class);
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(sysUser.getUsername(), sysUser.getPassword(), Lists.newArrayList()));
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        SysUser sysUser = (SysUser) authResult.getPrincipal();
        String role = "";
        Collection<? extends GrantedAuthority> authorities = sysUser.getAuthorities();
        for (GrantedAuthority authority : authorities){
            role = authority.getAuthority();
        }
        String token = jwtHandler.createToken(sysUser.getUser().getId(), sysUser.getUser().getUserName(), role, false);
        response.setHeader(jwtProperties.getTokenHeader(), jwtProperties.getTokenPrefix() + token);
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        response.setCharacterEncoding(CharsetConstant.UTF8);
        response.setContentType(ContentTypeConstant.APPLICATION_JSON);
        response.getWriter().println(JsonUtil.toJsonString(ResultVOUtil.parse(ResponseCodeEnum.ERROR, failed.getMessage())));
        response.getWriter().flush();
    }

}
